{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.datasets import load_wine\n",
    "from sklearn.model_selection import train_test_split,StratifiedKFold,cross_val_predict\n",
    "from sklearn.metrics import confusion_matrix,accuracy_score,recall_score,f1_score\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.svm import SVC\n",
    "import pandas as pd\n",
    "from sklearn.impute import SimpleImputer\n",
    "import numpy as np\n",
    "from sklearn.model_selection import cross_val_score,KFold\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from tensorflow.keras.callbacks import EarlyStopping\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense, Dropout\n",
    "import numpy as np\n",
    "from sklearn.ensemble import VotingClassifier\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 读取数据并划分训练集和测试集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>mpg</th>\n",
       "      <th>cylinders</th>\n",
       "      <th>displacement</th>\n",
       "      <th>horsepower</th>\n",
       "      <th>weight</th>\n",
       "      <th>acceleration</th>\n",
       "      <th>year</th>\n",
       "      <th>class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18.0</td>\n",
       "      <td>8</td>\n",
       "      <td>307.0</td>\n",
       "      <td>130</td>\n",
       "      <td>3504</td>\n",
       "      <td>12.0</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>15.0</td>\n",
       "      <td>8</td>\n",
       "      <td>350.0</td>\n",
       "      <td>165</td>\n",
       "      <td>3693</td>\n",
       "      <td>11.5</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>18.0</td>\n",
       "      <td>8</td>\n",
       "      <td>318.0</td>\n",
       "      <td>150</td>\n",
       "      <td>3436</td>\n",
       "      <td>11.0</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>16.0</td>\n",
       "      <td>8</td>\n",
       "      <td>304.0</td>\n",
       "      <td>150</td>\n",
       "      <td>3433</td>\n",
       "      <td>12.0</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>17.0</td>\n",
       "      <td>8</td>\n",
       "      <td>302.0</td>\n",
       "      <td>140</td>\n",
       "      <td>3449</td>\n",
       "      <td>10.5</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>392</th>\n",
       "      <td>27.0</td>\n",
       "      <td>4</td>\n",
       "      <td>140.0</td>\n",
       "      <td>86</td>\n",
       "      <td>2790</td>\n",
       "      <td>15.6</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>393</th>\n",
       "      <td>44.0</td>\n",
       "      <td>4</td>\n",
       "      <td>97.0</td>\n",
       "      <td>52</td>\n",
       "      <td>2130</td>\n",
       "      <td>24.6</td>\n",
       "      <td>82</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>394</th>\n",
       "      <td>32.0</td>\n",
       "      <td>4</td>\n",
       "      <td>135.0</td>\n",
       "      <td>84</td>\n",
       "      <td>2295</td>\n",
       "      <td>11.6</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>395</th>\n",
       "      <td>28.0</td>\n",
       "      <td>4</td>\n",
       "      <td>120.0</td>\n",
       "      <td>79</td>\n",
       "      <td>2625</td>\n",
       "      <td>18.6</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>396</th>\n",
       "      <td>31.0</td>\n",
       "      <td>4</td>\n",
       "      <td>119.0</td>\n",
       "      <td>82</td>\n",
       "      <td>2720</td>\n",
       "      <td>19.4</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>397 rows × 8 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "      mpg  cylinders  displacement horsepower  weight  acceleration  year  \\\n",
       "0    18.0          8         307.0        130    3504          12.0    70   \n",
       "1    15.0          8         350.0        165    3693          11.5    70   \n",
       "2    18.0          8         318.0        150    3436          11.0    70   \n",
       "3    16.0          8         304.0        150    3433          12.0    70   \n",
       "4    17.0          8         302.0        140    3449          10.5    70   \n",
       "..    ...        ...           ...        ...     ...           ...   ...   \n",
       "392  27.0          4         140.0         86    2790          15.6    82   \n",
       "393  44.0          4          97.0         52    2130          24.6    82   \n",
       "394  32.0          4         135.0         84    2295          11.6    82   \n",
       "395  28.0          4         120.0         79    2625          18.6    82   \n",
       "396  31.0          4         119.0         82    2720          19.4    82   \n",
       "\n",
       "     class  \n",
       "0        1  \n",
       "1        1  \n",
       "2        1  \n",
       "3        1  \n",
       "4        1  \n",
       "..     ...  \n",
       "392      1  \n",
       "393      2  \n",
       "394      1  \n",
       "395      1  \n",
       "396      1  \n",
       "\n",
       "[397 rows x 8 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "original_data = pd.read_csv(\"D:\\Lenovo\\Desktop\\云南大学\\空间数据挖掘\\实验数据\\实验数据2.csv\")\n",
    "original_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>mpg</th>\n",
       "      <th>cylinders</th>\n",
       "      <th>displacement</th>\n",
       "      <th>horsepower</th>\n",
       "      <th>weight</th>\n",
       "      <th>acceleration</th>\n",
       "      <th>year</th>\n",
       "      <th>class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18.0</td>\n",
       "      <td>8</td>\n",
       "      <td>307.0</td>\n",
       "      <td>130</td>\n",
       "      <td>3504</td>\n",
       "      <td>12.0</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>15.0</td>\n",
       "      <td>8</td>\n",
       "      <td>350.0</td>\n",
       "      <td>165</td>\n",
       "      <td>3693</td>\n",
       "      <td>11.5</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>18.0</td>\n",
       "      <td>8</td>\n",
       "      <td>318.0</td>\n",
       "      <td>150</td>\n",
       "      <td>3436</td>\n",
       "      <td>11.0</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>16.0</td>\n",
       "      <td>8</td>\n",
       "      <td>304.0</td>\n",
       "      <td>150</td>\n",
       "      <td>3433</td>\n",
       "      <td>12.0</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>17.0</td>\n",
       "      <td>8</td>\n",
       "      <td>302.0</td>\n",
       "      <td>140</td>\n",
       "      <td>3449</td>\n",
       "      <td>10.5</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>392</th>\n",
       "      <td>27.0</td>\n",
       "      <td>4</td>\n",
       "      <td>140.0</td>\n",
       "      <td>86</td>\n",
       "      <td>2790</td>\n",
       "      <td>15.6</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>393</th>\n",
       "      <td>44.0</td>\n",
       "      <td>4</td>\n",
       "      <td>97.0</td>\n",
       "      <td>52</td>\n",
       "      <td>2130</td>\n",
       "      <td>24.6</td>\n",
       "      <td>82</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>394</th>\n",
       "      <td>32.0</td>\n",
       "      <td>4</td>\n",
       "      <td>135.0</td>\n",
       "      <td>84</td>\n",
       "      <td>2295</td>\n",
       "      <td>11.6</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>395</th>\n",
       "      <td>28.0</td>\n",
       "      <td>4</td>\n",
       "      <td>120.0</td>\n",
       "      <td>79</td>\n",
       "      <td>2625</td>\n",
       "      <td>18.6</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>396</th>\n",
       "      <td>31.0</td>\n",
       "      <td>4</td>\n",
       "      <td>119.0</td>\n",
       "      <td>82</td>\n",
       "      <td>2720</td>\n",
       "      <td>19.4</td>\n",
       "      <td>82</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>392 rows × 8 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "      mpg  cylinders  displacement horsepower  weight  acceleration  year  \\\n",
       "0    18.0          8         307.0        130    3504          12.0    70   \n",
       "1    15.0          8         350.0        165    3693          11.5    70   \n",
       "2    18.0          8         318.0        150    3436          11.0    70   \n",
       "3    16.0          8         304.0        150    3433          12.0    70   \n",
       "4    17.0          8         302.0        140    3449          10.5    70   \n",
       "..    ...        ...           ...        ...     ...           ...   ...   \n",
       "392  27.0          4         140.0         86    2790          15.6    82   \n",
       "393  44.0          4          97.0         52    2130          24.6    82   \n",
       "394  32.0          4         135.0         84    2295          11.6    82   \n",
       "395  28.0          4         120.0         79    2625          18.6    82   \n",
       "396  31.0          4         119.0         82    2720          19.4    82   \n",
       "\n",
       "     class  \n",
       "0        1  \n",
       "1        1  \n",
       "2        1  \n",
       "3        1  \n",
       "4        1  \n",
       "..     ...  \n",
       "392      1  \n",
       "393      2  \n",
       "394      1  \n",
       "395      1  \n",
       "396      1  \n",
       "\n",
       "[392 rows x 8 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#进行数据清洗，删除包含“？”的行\n",
    "# 将 \"?\" 替换为 NaN\n",
    "original_data.replace('?', np.nan, inplace=True)\n",
    "\n",
    "# 删除包含 \"?\" 的行\n",
    "original_data.dropna(inplace=True)\n",
    "original_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(313, 7) (79, 7) (313,) (79,)\n"
     ]
    }
   ],
   "source": [
    "# 划分训练集和测试集，划分20%作为测试集\n",
    "label_encoder = LabelEncoder()\n",
    "original_data['class'] = label_encoder.fit_transform(original_data['class'])\n",
    "X_train, X_test, Y_train, Y_test = train_test_split(original_data.drop('class', axis=1), original_data['class'], test_size=0.2, random_state=42)\n",
    "print(X_train.shape, X_test.shape, Y_train.shape, Y_test.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 贝叶斯分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GaussianNB()\n"
     ]
    }
   ],
   "source": [
    "# 未指定先验概率分布\n",
    "clf=GaussianNB()\n",
    "clf.fit(X_train,Y_train)\n",
    "print(clf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "48 20 63 16 0 0\n"
     ]
    }
   ],
   "source": [
    "# 指定先验概率分布，以每个类在训练集中的占比作为先验概率\n",
    "print(sum(Y_train==1),sum(Y_test==1),sum(Y_train==2),sum(Y_test==2),sum(Y_train==3),sum(Y_test==3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GaussianNB(priors=[0.625, 0.17346938775510204, 0.20153061224489796])\n"
     ]
    }
   ],
   "source": [
    "clfp=GaussianNB(priors=[245/392,68/392,79/392])\n",
    "clfp.fit(X_train,Y_train)\n",
    "print(clfp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型精度评价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.6837060702875399\n",
      "测试集精度： 0.6455696202531646\n"
     ]
    }
   ],
   "source": [
    "# 未指定先验概率分布的情形（使用Y预测值与Y实际值相等的比例判定精度）\n",
    "\n",
    "y_pred_train = clf.predict(X_train)\n",
    "y_pred_test = clf.predict(X_test)\n",
    "train_accuracy=sum(y_pred_train==Y_train)/len(Y_train)\n",
    "test_accuracy=sum(y_pred_test==Y_test)/len(Y_test)\n",
    "print(\"训练集精度：\",train_accuracy)\n",
    "print(\"测试集精度：\",test_accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集交叉验证精度: 0.67378 (+/- 0.15190)\n",
      "测试集交叉验证精度: 0.63250 (+/- 0.21714)\n"
     ]
    }
   ],
   "source": [
    "# 交叉验证未指定先验概率的模型\n",
    "train_scores = cross_val_score(clf, X_train, Y_train, cv=5,scoring='accuracy')\n",
    "test_scores = cross_val_score(clf, X_test, Y_test, cv=5,scoring='accuracy')\n",
    "print(\"训练集交叉验证精度: %0.5f (+/- %0.5f)\" % (train_scores.mean(), train_scores.std() * 2))\n",
    "print(\"测试集交叉验证精度: %0.5f (+/- %0.5f)\" % (test_scores.mean(), test_scores.std() * 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.6837060702875399\n",
      "测试集精度： 0.6455696202531646\n"
     ]
    }
   ],
   "source": [
    "# 指定先验概率分布的情形\n",
    "y_pred_trainp = clfp.predict(X_train)\n",
    "y_pred_testp = clfp.predict(X_test)\n",
    "train_accuracyp=sum(y_pred_trainp==Y_train)/len(Y_train)\n",
    "test_accuracyp=sum(y_pred_testp==Y_test)/len(Y_test)\n",
    "print(\"训练集精度：\",train_accuracyp)\n",
    "print(\"测试集精度：\",test_accuracyp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集交叉验证精度: 0.67378 (+/- 0.15190)\n",
      "测试集交叉验证精度: 0.62000 (+/- 0.17790)\n"
     ]
    }
   ],
   "source": [
    "train_scoresp = cross_val_score(clfp, X_train, Y_train, cv=5)\n",
    "test_scoresp = cross_val_score(clfp, X_test, Y_test, cv=5)\n",
    "print(\"训练集交叉验证精度: %0.5f (+/- %0.5f)\" % (train_scoresp.mean(), train_scoresp.std() * 2))\n",
    "print(\"测试集交叉验证精度: %0.5f (+/- %0.5f)\" % (test_scoresp.mean(), test_scoresp.std() * 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[33  6  4]\n",
      " [ 1  7 12]\n",
      " [ 2  3 11]]\n"
     ]
    }
   ],
   "source": [
    "# 混淆矩阵\n",
    "con_mat=confusion_matrix(Y_test,y_pred_test)\n",
    "print(con_mat)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用K折交叉验证提升精度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 未知先验概率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy_score: 0.8125 recall_score: 0.8125 f1_score: 0.8125\n",
      "accuracy_score: 0.6875 recall_score: 0.6875 f1_score: 0.6875\n",
      "accuracy_score: 0.5625 recall_score: 0.5625 f1_score: 0.5625\n",
      "accuracy_score: 0.7741935483870968 recall_score: 0.7741935483870968 f1_score: 0.7741935483870968\n",
      "accuracy_score: 0.6774193548387096 recall_score: 0.6774193548387096 f1_score: 0.6774193548387096\n",
      "accuracy_score: 0.6451612903225806 recall_score: 0.6451612903225806 f1_score: 0.6451612903225806\n",
      "accuracy_score: 0.7096774193548387 recall_score: 0.7096774193548387 f1_score: 0.7096774193548389\n",
      "accuracy_score: 0.6774193548387096 recall_score: 0.6774193548387096 f1_score: 0.6774193548387096\n",
      "accuracy_score: 0.8064516129032258 recall_score: 0.8064516129032258 f1_score: 0.8064516129032258\n",
      "accuracy_score: 0.45161290322580644 recall_score: 0.45161290322580644 f1_score: 0.45161290322580644\n",
      "Accuracy: 0.68044 (+/- 0.21028)\n",
      "Recall: 0.68044 (+/- 0.21028)\n",
      "F1_score: 0.68044 (+/- 0.21028)\n",
      "Best model accuracy: 0.8125\n"
     ]
    }
   ],
   "source": [
    "# 使用K=10的情况找出最好的模型\n",
    "skfolds = StratifiedKFold(n_splits=10,shuffle=True,random_state=1)\n",
    "accuracy_score_list,recall_score_list,f1_score_list = [],[],[]\n",
    "\n",
    "# 初始化变量来保存最佳模型和性能指标\n",
    "best_clf = None\n",
    "best_accuracy = 0\n",
    "models = []\n",
    "\n",
    "for train_index,test_index in skfolds.split(X_train,Y_train):\n",
    "    # 准备交叉验证的数据\n",
    "    X_train_fold = X_train.iloc[train_index]\n",
    "    Y_train_fold = Y_train.iloc[train_index]\n",
    "    X_test_fold = X_train.iloc[test_index]\n",
    "    Y_test_fold = Y_train.iloc[test_index]\n",
    "    # 训练模型\n",
    "    clf.fit(X_train_fold,Y_train_fold)\n",
    "    y_pred = clf.predict(X_test_fold)\n",
    "    # 评估模型\n",
    "    AccuracyScore = accuracy_score(Y_test_fold,y_pred)\n",
    "    RecallScore = recall_score(Y_test_fold,y_pred,average='micro')\n",
    "    F1Score = f1_score(Y_test_fold,y_pred,average='micro')\n",
    "    # 将评估指标存放对应的列表中\n",
    "    accuracy_score_list.append(AccuracyScore)\n",
    "    recall_score_list.append(RecallScore)\n",
    "    f1_score_list.append(F1Score)\n",
    "\n",
    "    #将每次训练好的模型存放入models列表中\n",
    "    models.append(clf)\n",
    "\n",
    "    # 如果当前模型的性能优于之前的最佳模型，则保存当前模型\n",
    "    if AccuracyScore > best_accuracy:\n",
    "        best_accuracy = AccuracyScore\n",
    "        best_clf = clf\n",
    "\n",
    "    # 打印每一次训练的正确率、召回率、F1值\n",
    "    print('accuracy_score:',AccuracyScore,'recall_score:',RecallScore,'f1_score:',F1Score)\n",
    "# 打印各指标的平均值和95%的置信区间\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (np.average(accuracy_score_list), np.std(accuracy_score_list) * 2))\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (np.average(recall_score_list), np.std(recall_score_list) * 2))\n",
    "print(\"F1_score: %0.5f (+/- %0.5f)\" % (np.average(f1_score_list), np.std(f1_score_list) * 2))\n",
    "\n",
    "# 使用投票的方式融合模型\n",
    "voting_clf = VotingClassifier(estimators=[('model'+str(i), model) for i, model in enumerate(models)], voting='hard')\n",
    "voting_clf.fit(X_train, Y_train)\n",
    "\n",
    "\n",
    "# 打印最佳模型的性能指标\n",
    "print(\"Best model accuracy:\", best_accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.6805111821086262\n",
      "测试集精度： 0.6455696202531646\n",
      "训练集交叉验证精度： 0.6737839221710189\n",
      "测试集交叉验证精度： 0.6325000000000001\n"
     ]
    }
   ],
   "source": [
    "# 使用最佳模型进行测试\n",
    "\n",
    "y_pred_trainp = best_clf.predict(X_train)\n",
    "y_pred_testp = best_clf.predict(X_test)\n",
    "train_accuracyp=sum(y_pred_trainp==Y_train)/len(Y_train)\n",
    "test_accuracyp=sum(y_pred_testp==Y_test)/len(Y_test)\n",
    "print(\"训练集精度：\",train_accuracyp)\n",
    "print(\"测试集精度：\",test_accuracyp)\n",
    "\n",
    "train_scoresp = cross_val_score(best_clf, X_train, Y_train, cv=5)\n",
    "test_scoresp = cross_val_score(best_clf, X_test, Y_test, cv=5)\n",
    "print(\"训练集交叉验证精度：\", train_scoresp.mean())\n",
    "print(\"测试集交叉验证精度：\", test_scoresp.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.6837060702875399\n",
      "测试集精度： 0.6455696202531646\n",
      "训练集交叉验证精度： 0.6737839221710189\n",
      "测试集交叉验证精度： 0.6325000000000001\n"
     ]
    }
   ],
   "source": [
    "#使用融合模型进行测试\n",
    "y_pred_trainp = voting_clf.predict(X_train)\n",
    "y_pred_testp = voting_clf.predict(X_test)\n",
    "train_accuracyp=sum(y_pred_trainp==Y_train)/len(Y_train)\n",
    "test_accuracyp=sum(y_pred_testp==Y_test)/len(Y_test)\n",
    "print(\"训练集精度：\",train_accuracyp)\n",
    "print(\"测试集精度：\",test_accuracyp)\n",
    "\n",
    "train_scoresp = cross_val_score(best_clf, X_train, Y_train, cv=5)\n",
    "test_scoresp = cross_val_score(best_clf, X_test, Y_test, cv=5)\n",
    "print(\"训练集交叉验证精度：\", train_scoresp.mean())\n",
    "print(\"测试集交叉验证精度：\", test_scoresp.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 已知先验概率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy_score: 0.8125 recall_score: 0.8125 f1_score: 0.8125\n",
      "accuracy_score: 0.6875 recall_score: 0.6875 f1_score: 0.6875\n",
      "accuracy_score: 0.5625 recall_score: 0.5625 f1_score: 0.5625\n",
      "accuracy_score: 0.7741935483870968 recall_score: 0.7741935483870968 f1_score: 0.7741935483870968\n",
      "accuracy_score: 0.6774193548387096 recall_score: 0.6774193548387096 f1_score: 0.6774193548387096\n",
      "accuracy_score: 0.6451612903225806 recall_score: 0.6451612903225806 f1_score: 0.6451612903225806\n",
      "accuracy_score: 0.7096774193548387 recall_score: 0.7096774193548387 f1_score: 0.7096774193548389\n",
      "accuracy_score: 0.6774193548387096 recall_score: 0.6774193548387096 f1_score: 0.6774193548387096\n",
      "accuracy_score: 0.8064516129032258 recall_score: 0.8064516129032258 f1_score: 0.8064516129032258\n",
      "accuracy_score: 0.45161290322580644 recall_score: 0.45161290322580644 f1_score: 0.45161290322580644\n",
      "Accuracy: 0.68044 (+/- 0.21028)\n",
      "Recall: 0.68044 (+/- 0.21028)\n",
      "F1_score: 0.68044 (+/- 0.21028)\n",
      "Best model accuracy: 0.8125\n"
     ]
    }
   ],
   "source": [
    "# 使用K=10的情况找出最好的模型\n",
    "skfolds = StratifiedKFold(n_splits=10,shuffle=True,random_state=1)\n",
    "accuracy_score_list,recall_score_list,f1_score_list = [],[],[]\n",
    "\n",
    "# 初始化变量来保存最佳模型和性能指标\n",
    "best_clfp = None\n",
    "best_accuracy = 0\n",
    "models = []\n",
    "\n",
    "for train_index,test_index in skfolds.split(X_train,Y_train):\n",
    "    # 准备交叉验证的数据\n",
    "    X_train_fold = X_train.iloc[train_index]\n",
    "    Y_train_fold = Y_train.iloc[train_index]\n",
    "    X_test_fold = X_train.iloc[test_index]\n",
    "    Y_test_fold = Y_train.iloc[test_index]\n",
    "    # 训练模型\n",
    "    clfp.fit(X_train_fold,Y_train_fold)\n",
    "    y_pred = clfp.predict(X_test_fold)\n",
    "    # 评估模型\n",
    "    AccuracyScore = accuracy_score(Y_test_fold,y_pred)\n",
    "    RecallScore = recall_score(Y_test_fold,y_pred,average='micro')\n",
    "    F1Score = f1_score(Y_test_fold,y_pred,average='micro')\n",
    "    # 将评估指标存放对应的列表中\n",
    "    accuracy_score_list.append(AccuracyScore)\n",
    "    recall_score_list.append(RecallScore)\n",
    "    f1_score_list.append(F1Score)\n",
    "\n",
    "    models.append(clfp)\n",
    "\n",
    "    # 如果当前模型的性能优于之前的最佳模型，则保存当前模型\n",
    "    if AccuracyScore > best_accuracy:\n",
    "        best_accuracy = AccuracyScore\n",
    "        best_clfp = clfp\n",
    "\n",
    "    # 打印每一次训练的正确率、召回率、F1值\n",
    "    print('accuracy_score:',AccuracyScore,'recall_score:',RecallScore,'f1_score:',F1Score)\n",
    "# 打印各指标的平均值和95%的置信区间\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (np.average(accuracy_score_list), np.std(accuracy_score_list) * 2))\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (np.average(recall_score_list), np.std(recall_score_list) * 2))\n",
    "print(\"F1_score: %0.5f (+/- %0.5f)\" % (np.average(f1_score_list), np.std(f1_score_list) * 2))\n",
    "\n",
    "# 使用投票的方式融合模型\n",
    "voting_clfp = VotingClassifier(estimators=[('model'+str(i), model) for i, model in enumerate(models)], voting='hard')\n",
    "voting_clfp.fit(X_train, Y_train)\n",
    "\n",
    "\n",
    "# 打印最佳模型的性能指标\n",
    "print(\"Best model accuracy:\", best_accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.6741214057507987\n",
      "测试集精度： 0.6455696202531646\n",
      "训练集交叉验证精度： 0.6737839221710189\n",
      "测试集交叉验证精度： 0.62\n"
     ]
    }
   ],
   "source": [
    "# 使用最佳模型进行测试\n",
    "\n",
    "y_pred_trainp = best_clfp.predict(X_train)\n",
    "y_pred_testp = best_clfp.predict(X_test)\n",
    "train_accuracyp=sum(y_pred_trainp==Y_train)/len(Y_train)\n",
    "test_accuracyp=sum(y_pred_testp==Y_test)/len(Y_test)\n",
    "print(\"训练集精度：\",train_accuracyp)\n",
    "print(\"测试集精度：\",test_accuracyp)\n",
    "\n",
    "train_scoresp = cross_val_score(best_clfp, X_train, Y_train, cv=5)\n",
    "test_scoresp = cross_val_score(best_clfp, X_test, Y_test, cv=5)\n",
    "print(\"训练集交叉验证精度：\", train_scoresp.mean())\n",
    "print(\"测试集交叉验证精度：\", test_scoresp.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.6837060702875399\n",
      "测试集精度： 0.6455696202531646\n",
      "训练集交叉验证精度： 0.6737839221710189\n",
      "测试集交叉验证精度： 0.6325000000000001\n"
     ]
    }
   ],
   "source": [
    "#使用融合模型进行测试\n",
    "y_pred_trainp = voting_clfp.predict(X_train)\n",
    "y_pred_testp = voting_clfp.predict(X_test)\n",
    "train_accuracyp=sum(y_pred_trainp==Y_train)/len(Y_train)\n",
    "test_accuracyp=sum(y_pred_testp==Y_test)/len(Y_test)\n",
    "print(\"训练集精度：\",train_accuracyp)\n",
    "print(\"测试集精度：\",test_accuracyp)\n",
    "\n",
    "train_scoresp = cross_val_score(best_clf, X_train, Y_train, cv=5)\n",
    "test_scoresp = cross_val_score(best_clf, X_test, Y_test, cv=5)\n",
    "print(\"训练集交叉验证精度：\", train_scoresp.mean())\n",
    "print(\"测试集交叉验证精度：\", test_scoresp.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 神经网络分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/50\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Lenovo\\AppData\\Roaming\\Python\\Python39\\site-packages\\keras\\src\\layers\\core\\dense.py:86: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n",
      "  super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 35ms/step - accuracy: 0.1734 - loss: 1.6775 - val_accuracy: 0.1847 - val_loss: 1.3504\n",
      "Epoch 2/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - accuracy: 0.2824 - loss: 1.2643 - val_accuracy: 0.2166 - val_loss: 1.0865\n",
      "Epoch 3/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - accuracy: 0.3451 - loss: 1.1099 - val_accuracy: 0.6561 - val_loss: 0.9166\n",
      "Epoch 4/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - accuracy: 0.5643 - loss: 0.9886 - val_accuracy: 0.6561 - val_loss: 0.8822\n",
      "Epoch 5/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - accuracy: 0.6335 - loss: 0.9574 - val_accuracy: 0.6561 - val_loss: 0.8881\n",
      "Epoch 6/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - accuracy: 0.6547 - loss: 0.9035 - val_accuracy: 0.6561 - val_loss: 0.8965\n",
      "Epoch 7/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - accuracy: 0.6495 - loss: 0.9247 - val_accuracy: 0.6561 - val_loss: 0.8963\n",
      "Epoch 8/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 6ms/step - accuracy: 0.6712 - loss: 0.8635 - val_accuracy: 0.6561 - val_loss: 0.8918\n",
      "Epoch 9/50\n",
      "\u001b[1m5/5\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 7ms/step - accuracy: 0.6430 - loss: 0.9038 - val_accuracy: 0.6561 - val_loss: 0.8885\n",
      "\u001b[1m10/10\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 889us/step - accuracy: 0.6356 - loss: 0.9076\n",
      "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 2ms/step - accuracy: 0.5143 - loss: 1.0797 \n",
      "训练集精度： 0.6453673839569092\n",
      "测试集精度 0.5443037748336792\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# 构建深度神经网络模型\n",
    "model = Sequential([\n",
    "    Dense(64, activation='sigmoid', input_shape=(X_train.shape[1],)),\n",
    "    Dropout(0.2),\n",
    "    Dense(64, activation='sigmoid'),\n",
    "    Dropout(0.2),\n",
    "    Dense(3, activation='sigmoid')\n",
    "])\n",
    "\n",
    "# 编译模型\n",
    "model.compile(optimizer='adam',\n",
    "              loss='sparse_categorical_crossentropy',\n",
    "              metrics=['accuracy'])\n",
    "\n",
    "# 定义提前停止训练的回调函数\n",
    "early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)\n",
    "\n",
    "# 训练模型\n",
    "model.fit(X_train, Y_train, epochs=50, batch_size=32, validation_split=0.5,callbacks=[early_stopping])\n",
    "\n",
    "# 评估模型\n",
    "train_loss, train_accuracy = model.evaluate(X_train, Y_train)\n",
    "test_loss, test_accuracy = model.evaluate(X_test, Y_test)\n",
    "print(\"训练集精度：\", train_accuracy)\n",
    "print(\"测试集精度\", test_accuracy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# KNN分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 1.0\n",
      "测试集精度： 0.6329113924050633\n"
     ]
    }
   ],
   "source": [
    "knn = KNeighborsClassifier(n_neighbors=3,weights='distance') # n_neighbors即为K值\n",
    "knn.fit(X_train, Y_train)\n",
    "Y_train_pred = knn.predict(X_train)\n",
    "Y_test_pred = knn.predict(X_test)\n",
    "train_accuracy = accuracy_score(Y_train, Y_train_pred)\n",
    "test_accuracy = accuracy_score(Y_test, Y_test_pred)\n",
    "print(\"训练集精度：\", train_accuracy)\n",
    "print(\"测试集精度：\", test_accuracy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## KNN分类+K折交叉验证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy_score: 0.875 recall_score: 0.875 f1_score: 0.875\n",
      "accuracy_score: 0.6875 recall_score: 0.6875 f1_score: 0.6875\n",
      "accuracy_score: 0.71875 recall_score: 0.71875 f1_score: 0.71875\n",
      "accuracy_score: 0.9354838709677419 recall_score: 0.9354838709677419 f1_score: 0.9354838709677419\n",
      "accuracy_score: 0.7419354838709677 recall_score: 0.7419354838709677 f1_score: 0.7419354838709677\n",
      "accuracy_score: 0.6774193548387096 recall_score: 0.6774193548387096 f1_score: 0.6774193548387096\n",
      "accuracy_score: 0.7419354838709677 recall_score: 0.7419354838709677 f1_score: 0.7419354838709677\n",
      "accuracy_score: 0.7096774193548387 recall_score: 0.7096774193548387 f1_score: 0.7096774193548389\n",
      "accuracy_score: 0.7741935483870968 recall_score: 0.7741935483870968 f1_score: 0.7741935483870968\n",
      "accuracy_score: 0.7419354838709677 recall_score: 0.7419354838709677 f1_score: 0.7419354838709677\n",
      "Accuracy: 0.76038 (+/- 0.15685)\n",
      "Recall: 0.76038 (+/- 0.15685)\n",
      "F1_score: 0.76038 (+/- 0.15685)\n",
      "Best model accuracy: 0.9354838709677419\n"
     ]
    }
   ],
   "source": [
    "knn = KNeighborsClassifier(n_neighbors=3,weights='distance')\n",
    "# 使用K=10的情况找出最好的模型\n",
    "skfolds = StratifiedKFold(n_splits=10,shuffle=True,random_state=1)\n",
    "accuracy_score_list,recall_score_list,f1_score_list = [],[],[]\n",
    "\n",
    "# 初始化变量来保存最佳模型和性能指标\n",
    "best_knn = None\n",
    "best_accuracy = 0\n",
    "\n",
    "for train_index,test_index in skfolds.split(X_train,Y_train):\n",
    "    # 准备交叉验证的数据\n",
    "    X_train_fold = X_train.iloc[train_index]\n",
    "    Y_train_fold = Y_train.iloc[train_index]\n",
    "    X_test_fold = X_train.iloc[test_index]\n",
    "    Y_test_fold = Y_train.iloc[test_index]\n",
    "    # 训练模型\n",
    "    knn.fit(X_train_fold,Y_train_fold)\n",
    "    y_pred = knn.predict(X_test_fold)\n",
    "    # 评估模型\n",
    "    AccuracyScore = accuracy_score(Y_test_fold,y_pred)\n",
    "    RecallScore = recall_score(Y_test_fold,y_pred,average='micro')\n",
    "    F1Score = f1_score(Y_test_fold,y_pred,average='micro')\n",
    "    # 将评估指标存放对应的列表中\n",
    "    accuracy_score_list.append(AccuracyScore)\n",
    "    recall_score_list.append(RecallScore)\n",
    "    f1_score_list.append(F1Score)\n",
    "\n",
    "    # 如果当前模型的性能优于之前的最佳模型，则保存当前模型\n",
    "    if AccuracyScore > best_accuracy:\n",
    "        best_accuracy = AccuracyScore\n",
    "        best_knn = knn\n",
    "\n",
    "    # 打印每一次训练的正确率、召回率、F1值\n",
    "    print('accuracy_score:',AccuracyScore,'recall_score:',RecallScore,'f1_score:',F1Score)\n",
    "# 打印各指标的平均值和95%的置信区间\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (np.average(accuracy_score_list), np.std(accuracy_score_list) * 2))\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (np.average(recall_score_list), np.std(recall_score_list) * 2))\n",
    "print(\"F1_score: %0.5f (+/- %0.5f)\" % (np.average(f1_score_list), np.std(f1_score_list) * 2))\n",
    "\n",
    "# 打印最佳模型的性能指标\n",
    "print(\"Best model accuracy:\", best_accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.9744408945686901\n",
      "测试集精度： 0.620253164556962\n"
     ]
    }
   ],
   "source": [
    "Y_train_pred = best_knn.predict(X_train)\n",
    "Y_test_pred = best_knn.predict(X_test)\n",
    "train_accuracy = accuracy_score(Y_train, Y_train_pred)\n",
    "test_accuracy = accuracy_score(Y_test, Y_test_pred)\n",
    "print(\"训练集精度：\", train_accuracy)\n",
    "print(\"测试集精度：\", test_accuracy)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 支持向量机分类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.8146964856230032\n",
      "测试集精度： 0.759493670886076\n"
     ]
    }
   ],
   "source": [
    "svm = SVC(kernel='linear') # 可以选择不同的核函数，如'linear', 'poly', 'rbf', 'sigmoid'等\n",
    "svm.fit(X_train, Y_train)\n",
    "Y_train_pred = svm.predict(X_train)\n",
    "Y_test_pred = svm.predict(X_test)\n",
    "train_accuracy = accuracy_score(Y_train, Y_train_pred)\n",
    "test_accuracy = accuracy_score(Y_test, Y_test_pred)\n",
    "print(\"训练集精度：\", train_accuracy)\n",
    "print(\"测试集精度：\", test_accuracy)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 支持向量机分类测试结果(random_state=0)：\n",
    "### linear函数：\n",
    "训练集精度： 0.8083067092651757     \n",
    "测试集精度： 0.759493670886076\n",
    "### poly核函数 \n",
    "训练集精度： 0.6900958466453674    \n",
    "测试集精度： 0.6708860759493671\n",
    "### rbf核函数\n",
    "训练集精度： 0.6932907348242812      \n",
    "测试集精度： 0.6962025316455697\n",
    "### sigmoid核函数\n",
    "训练集精度： 0.4696485623003195      \n",
    "测试集精度： 0.4177215189873418"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线性支持向量机+KNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy_score: 0.84375 recall_score: 0.84375 f1_score: 0.84375\n",
      "accuracy_score: 0.75 recall_score: 0.75 f1_score: 0.75\n",
      "accuracy_score: 0.75 recall_score: 0.75 f1_score: 0.75\n",
      "accuracy_score: 0.9032258064516129 recall_score: 0.9032258064516129 f1_score: 0.9032258064516129\n",
      "accuracy_score: 0.8064516129032258 recall_score: 0.8064516129032258 f1_score: 0.8064516129032258\n",
      "accuracy_score: 0.7741935483870968 recall_score: 0.7741935483870968 f1_score: 0.7741935483870968\n",
      "accuracy_score: 0.7419354838709677 recall_score: 0.7419354838709677 f1_score: 0.7419354838709677\n",
      "accuracy_score: 0.6451612903225806 recall_score: 0.6451612903225806 f1_score: 0.6451612903225806\n",
      "accuracy_score: 0.8064516129032258 recall_score: 0.8064516129032258 f1_score: 0.8064516129032258\n",
      "accuracy_score: 0.6129032258064516 recall_score: 0.6129032258064516 f1_score: 0.6129032258064516\n",
      "Accuracy: 0.76341 (+/- 0.16405)\n",
      "Recall: 0.76341 (+/- 0.16405)\n",
      "F1_score: 0.76341 (+/- 0.16405)\n",
      "Best model accuracy: 0.9032258064516129\n"
     ]
    }
   ],
   "source": [
    "svm = SVC(kernel='linear')\n",
    "# 使用K=10的情况找出最好的模型\n",
    "skfolds = StratifiedKFold(n_splits=10,shuffle=True,random_state=1)\n",
    "accuracy_score_list,recall_score_list,f1_score_list = [],[],[]\n",
    "\n",
    "# 初始化变量来保存最佳模型和性能指标\n",
    "best_svm = None\n",
    "best_accuracy = 0\n",
    "\n",
    "for train_index,test_index in skfolds.split(X_train,Y_train):\n",
    "    # 准备交叉验证的数据\n",
    "    X_train_fold = X_train.iloc[train_index]\n",
    "    Y_train_fold = Y_train.iloc[train_index]\n",
    "    X_test_fold = X_train.iloc[test_index]\n",
    "    Y_test_fold = Y_train.iloc[test_index]\n",
    "    # 训练模型\n",
    "    svm.fit(X_train_fold,Y_train_fold)\n",
    "    y_pred = svm.predict(X_test_fold)\n",
    "    # 评估模型\n",
    "    AccuracyScore = accuracy_score(Y_test_fold,y_pred)\n",
    "    RecallScore = recall_score(Y_test_fold,y_pred,average='micro')\n",
    "    F1Score = f1_score(Y_test_fold,y_pred,average='micro')\n",
    "    # 将评估指标存放对应的列表中\n",
    "    accuracy_score_list.append(AccuracyScore)\n",
    "    recall_score_list.append(RecallScore)\n",
    "    f1_score_list.append(F1Score)\n",
    "\n",
    "    # 如果当前模型的性能优于之前的最佳模型，则保存当前模型\n",
    "    if AccuracyScore > best_accuracy:\n",
    "        best_accuracy = AccuracyScore\n",
    "        best_svm = svm\n",
    "\n",
    "    # 打印每一次训练的正确率、召回率、F1值\n",
    "    print('accuracy_score:',AccuracyScore,'recall_score:',RecallScore,'f1_score:',F1Score)\n",
    "# 打印各指标的平均值和95%的置信区间\n",
    "print(\"Accuracy: %0.5f (+/- %0.5f)\" % (np.average(accuracy_score_list), np.std(accuracy_score_list) * 2))\n",
    "print(\"Recall: %0.5f (+/- %0.5f)\" % (np.average(recall_score_list), np.std(recall_score_list) * 2))\n",
    "print(\"F1_score: %0.5f (+/- %0.5f)\" % (np.average(f1_score_list), np.std(f1_score_list) * 2))\n",
    "\n",
    "# 打印最佳模型的性能指标\n",
    "print(\"Best model accuracy:\", best_accuracy)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集精度： 0.8210862619808307\n",
      "测试集精度： 0.7341772151898734\n"
     ]
    }
   ],
   "source": [
    "Y_train_pred = best_svm.predict(X_train)\n",
    "Y_test_pred = best_svm.predict(X_test)\n",
    "train_accuracy = accuracy_score(Y_train, Y_train_pred)\n",
    "test_accuracy = accuracy_score(Y_test, Y_test_pred)\n",
    "print(\"训练集精度：\", train_accuracy)\n",
    "print(\"测试集精度：\", test_accuracy)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "myenv2",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
